PostgreSQL 全文搜索 文档解析函数

1 背景知识

全文搜索排序和去重是在输入文本期间自动完成的,因为要实现 全文搜索 必须从文档创建 tsvector 数据类型以及创建 tsquery 的查询。

PostgreSQL提供了函数 to_tsvector将一个文档转换成tsvector数据类型。

2 to_tsvector 函数语法定义

to_tsvector([ config regconfig, ] document text) returns tsvector
参数 说明
config regconfig 指定正规化的语言规则。
document text 指定要预处理的文档内容。
tsvector 返回数据类型。

3 to_tsvector 函数文本处理过程

  1. 调用 解析器,将文档文本分解成记号,并且为每一种记号分配一个类型。
  2. 对于每一个 记号,函数会去查询一个 词典 列表。 将 记号 正规化的 词位。例如,rats 变成 rat 是因为一个词典识别到该词 ratsrat 的复数形式。
  3. 因为有些单词出现得太频繁,无法搜索索引。所以一些词会被识别为停用词,这将忽略它们,在我们的例子中有 aonit 是停用词。
  4. 如果没有词典能识别该记号,那它将也会被忽略。例如,标点符号 - 就属于这种情况,因为事实上没有词典会给它分配记号类型(空间符号),即空间记号不会被索引。
  5. 对于解析器、词典以及要索引哪些记号类型是由所选择的 文本搜索配置 决定的。
  6. 可以在同一个数据库中有多种不同的配置,并且有用于很多种语言的预定义配置。在我们的例子中,我们使用适用英语的默认配置 english

4 to_tsvector 函数使用方式

SELECT to_tsvector('english', 'a fat  cat sat on a mat - it ate a fat rats');
//屏幕输出:
  to_tsvector                     
-----------------------------------------------------
 'ate':9 'cat':3 'fat':2,11 'mat':7 'rat':12 'sat':4
(1 row)
Note

从上面返回结果可知:
tsvector 不包含词 aonit,词 rats 变成了 rat,并且标点符号 - 被忽略了。

5 setweight 函数添加 词位 的权重

函数 setweight 用于对 tsvector 中的 词位 标注一个给定的 权重,这里一个 权重 可以是四个字母之一:ABCD。权重用来标记来自文档不同部分的项,例如标题、正文。权重信息可以被用来排名搜索结果。

因为 to_tsvector (NULL) 将返回 NULL,所以建议使用 coalesce 函数,避免空值造成的问题。
下面是从 film 表中创建一个 tsvector 的方法:

SELECT 
    setweight(to_tsvector(coalesce(title,'')), 'A')    ||
    setweight(to_tsvector(coalesce(special_features,'')), 'B')   FROM film ;
//屏幕输出:
?column?                         
------------------------------
 'behind':4B 'graffiti':2A 'scene':6B 'stranger':1A 'trailer':3B
 'behind':7B 'commentari':4B 'delet':5B 'person':2A 'scene':6B,9B 'trailer':3B 'weekend':1A
 'behind':5B 'cabin':2A 'commentari':4B 'scene':7B 'shock':1A 'trailer':3B
 'behind':4B 'blind':1A 'gun':2A 'scene':6B 'trailer':3B
 'behind':5B 'commentari':4B 'detail':2A 'motion':1A 'scene':7B 'trailer':3B
... ... ... ...

这里我们已经使用了 setweight 函数在 tsvector 标注每一个词位的来源,并将标注过的 tsvector 值用连接操作符 || 合并在一起。如果想要了解更多操作符请见 操作符

6 参考文档

参考链接:12.3. 控制文本搜索 (postgres.cn)